#include "Game.h"

Game::Game()
{
	LPDIRECT3D9         m_pD3D = NULL; // Used to create the D3DDevice
	LPDIRECT3DDEVICE9   m_pd3dDevice = NULL; // Our rendering device
	LPDIRECT3DVERTEXBUFFER9 m_pVB = NULL; // Buffer to hold ball vertices
	m_WinH=1000;
	m_WinW=1200;

// Register the window class
	WNDCLASSEX wc =
	{
		sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
		GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
		L"D3D Pong", NULL
	};
	RegisterClassEx( &wc );

	// Create the application's window
	m_hWnd = CreateWindow( L"D3D Pong", L"Pong",
		WS_OVERLAPPEDWINDOW, 100, 100, TheGame::Instance()->GetWinW(), TheGame::Instance()->GetWinH(),
		NULL, NULL, wc.hInstance, NULL );
	UnregisterClass( L"D3D Pong", wc.hInstance );
}
LRESULT WINAPI Game::MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
	case WM_DESTROY:
		
		PostQuitMessage( 0 );
		return 0;

	case WM_PAINT:
		
		ValidateRect( hWnd, NULL );
		return 0;
	}

	return DefWindowProc( hWnd, msg, wParam, lParam );
}
VOID Game::Run()
{
	TheGame::Instance()->Update();
	if( NULL == TheGame::Instance()->m_pd3dDevice )
		return;

	// Clear the backbuffer to a black color
	TheGame::Instance()->m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 );

	// Begin the scene
	if( SUCCEEDED( TheGame::Instance()->m_pd3dDevice->BeginScene() ) )
	{

		TheGame::Instance()->Draw();

		// End the scene
		TheGame::Instance()->m_pd3dDevice->EndScene();
	}

	// Present the backbuffer contents to the display
	TheGame::Instance()->m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
HRESULT Game::Load()
{
	m_PL=new Paddle;
	m_PL->SetPos(Vec2f(60,TheGame::Instance()->GetWinH()/2.0f));	//Tex init moved to Load function
	TheGame::Instance()->m_GameObjects.push_back(m_PL);

	m_PR=new Paddle;
	m_PR->SetPos(Vec2f((TheGame::Instance()->GetWinW())-60.0f,TheGame::Instance()->GetWinH()/2.0f));
	TheGame::Instance()->m_GameObjects.push_back(m_PR);

	m_Ball=new Ball;
	m_Ball->SetPos(Vec2f((float)TheGame::Instance()->GetWinW()/2.0f,TheGame::Instance()->GetWinH()/2.0f));
	TheGame::Instance()->m_GameObjects.push_back(m_Ball);

	m_score = new Text;
	m_score->SetPos(Vec2f((float)TheGame::Instance()->GetWinW()/2.0f, 10));
	m_score->SetSize(Vec2f(400, 100));
	static_cast<Text*>(m_score)->SetText("Score");
	TheGame::Instance()->m_GameObjects.push_back(m_score);

	for(unsigned int i=0;i<m_GameObjects.size();++i)
	{
		if(m_GameObjects[i]->Load()!=S_OK)
		{
			return E_FAIL;
		}
	}
	return S_OK;
}
void Game::Unload()
{
	for(unsigned int i=0;i<m_GameObjects.size();++i)
	{
		m_GameObjects[i]->Unload();
	}
	if( TheGame::Instance()->m_pd3dDevice != NULL )
		TheGame::Instance()->m_pd3dDevice->Release();

	if( TheGame::Instance()->m_pD3D != NULL )
		TheGame::Instance()->m_pD3D->Release();
}
void Game::Draw()
{
	for(unsigned int i=0;i<m_GameObjects.size();++i)
	{
		m_GameObjects[i]->Draw();
	}
}
void Game::Update()
{
	Paddle* right = static_cast<Paddle*>(m_PR);
	Paddle* left = static_cast<Paddle*>(m_PL);
	//Check if either side has scored
	if (m_Ball->GetPos().X() <= 0)
	{
		right->SetScore(right->GetScore() + 1);
		m_Ball->SetPos(Vec2f(Vec2f((float)TheGame::Instance()->GetWinW()/2.0f,TheGame::Instance()->GetWinH()/2.0f)));
		m_Ball->SetVel(Vec2f(5,0));
	}
	else if(m_Ball->GetPos().X() >= 1200)
	{
		left->SetScore(left->GetScore() + 1);
		m_Ball->SetPos(Vec2f(Vec2f((float)TheGame::Instance()->GetWinW()/2.0f,TheGame::Instance()->GetWinH()/2.0f)));
		m_Ball->SetVel(Vec2f(-5,0));
	}

	//Collision Tests
	if(m_Ball->Collision(m_PL->GetVolume()))
	{
		static_cast<Ball*>(m_Ball)->PaddleHit(m_PL->GetPos().Y());
	}
	else if(m_Ball->Collision(m_PR->GetVolume()))
	{
		static_cast<Ball*>(m_Ball)->PaddleHit(m_PR->GetPos().Y());
	}
	
	if(TheInputHandler::Instance()->KeyPressed(DIK_UP))
	{
		m_PR->SetVel(Vec2f(0,-10));
	}
	else if(TheInputHandler::Instance()->KeyPressed(DIK_DOWN))
	{
		m_PR->SetVel(Vec2f(0,10));
	}
	else
	{
		m_PR->SetVel(Vec2f(0,0));
	}

	if (TheInputHandler::Instance()->KeyPressed(DIK_W))
	{
		m_PL->SetVel(Vec2f(0,-10));
	}
	else if(TheInputHandler::Instance()->KeyPressed(DIK_S))
	{
		m_PL->SetVel(Vec2f(0,10));
	}
	else
	{
		m_PL->SetVel(Vec2f(0,0));
	}

	//Text update
	char tempText[5];
	_itoa_s(left->GetScore(), tempText, 10);
	std::string leftScore = tempText;

	_itoa_s(right->GetScore(), tempText, 10);
	std::string rightScore = tempText;
	
	std::string score = leftScore;
	score += " - ";
	score += rightScore;
	static_cast<Text*>(m_score)->SetText(score);

	TheInputHandler::Instance()->Update();
	for(unsigned int i=0;i<m_GameObjects.size();++i)
	{
		m_GameObjects[i]->Update();
	}
}
int Game::GetWinH()
{
	return m_WinH;
}
int Game::GetWinW()
{
	return m_WinW;

}
HWND Game::GetWindowHandle()
{
	return m_hWnd;
}